const vscode = require('vscode');
const { McpHub } = require('./McpHub');
const { ensureDirectoryExists } = require('../../utils/fs');
const path = require('path');
const fs = require('fs').promises;

class McpService {
    constructor(context) {
        this.mcpHub = null;
        this.context = context;
    }
    
    /**
     * 初始化MCP服务
     */
    async initialize() {
        try {
            if (this.mcpHub) {
                return; // 已初始化
            }
            
            // 获取插件版本
            const version = await this.getPackageVersion();
            console.log(`MCP服务版本: ${version}`);
            
            // 创建McpHub实例
            this.mcpHub = new McpHub(
                // 获取MCP服务器路径
                async () => {
                    return this.getSettingsFilePath('mcpServers.json');
                },
                // 获取设置目录路径
                async () => {
                    return this.getSettingsDirectoryPath();
                },
                // 发送消息到WebView
                async (message) => {
                    // 将消息发送到所有注册的WebView
                    this.notifyWebViews(message);
                },
                // 插件版本
                version
            );
            
            // 定期刷新服务器状态
            this.startRefreshTimer();
            
            // 立即获取一次服务器状态
            setTimeout(() => {
                this.refreshServerStatus();
            }, 1000);
            
            console.log('MCP服务已初始化');
        } catch (error) {
            console.error('初始化MCP服务失败:', error);
            throw error;
        }
    }
    
    /**
     * 启动刷新定时器，定期检查服务器状态
     */
    startRefreshTimer() {
        // 清理现有定时器
        if (this.refreshTimer) {
            clearInterval(this.refreshTimer);
        }
        
        // 每15秒刷新一次服务器状态
        this.refreshTimer = setInterval(() => {
            this.refreshServerStatus();
        }, 15000);
    }
    
    /**
     * 刷新服务器状态
     */
    async refreshServerStatus() {
        try {
            if (this.mcpHub) {
                // 刷新服务器状态并发送到WebView
                console.log('刷新服务器状态...');
                await this.mcpHub.sendLatestMcpServers();
            }
        } catch (error) {
            console.error('刷新服务器状态失败:', error);
        }
    }
    
    /**
     * 通知所有注册的WebView
     * @param {Object} message 消息对象
     */
    notifyWebViews(message) {
        try {
            // 查找所有MCP相关的WebView
            const mcpViews = vscode.window.visibleTextEditors
                .filter(editor => editor.document.uri.scheme === 'vscode-webview')
                .map(editor => editor.document.uri);
                
            // 发送消息到所有WebView
            for (const view of mcpViews) {
                try {
                    const webview = vscode.window.createWebviewPanel('mcpView', 'MCP', vscode.ViewColumn.One, {}).webview;
                    webview.postMessage(message);
                } catch (e) {
                    console.warn('向WebView发送消息失败:', e);
                }
            }
            
            // 记录消息
            console.log('向WebView发送MCP消息:', message);
        } catch (error) {
            console.error('通知WebView失败:', error);
        }
    }
    
    /**
     * 获取插件版本
     * @returns {Promise<string>} 版本号
     */
    async getPackageVersion() {
        try {
            // 尝试从package.json获取版本号
            const packageJsonPath = path.join(this.context.extensionPath, 'package.json');
            const packageJson = JSON.parse(await fs.readFile(packageJsonPath, 'utf-8'));
            return packageJson.version || '1.0.0';
        } catch (error) {
            console.warn('获取插件版本失败:', error);
            return '1.0.0';
        }
    }
    
    /**
     * 获取设置目录路径
     */
    async getSettingsDirectoryPath() {
        const dirPath = this.context.globalStorageUri.fsPath;
        // 确保目录存在
        await ensureDirectoryExists(dirPath);
        return dirPath;
    }
    
    /**
     * 获取设置文件路径
     */
    async getSettingsFilePath(fileName) {
        const storageUri = this.context.globalStorageUri;
        const filePath = vscode.Uri.joinPath(storageUri, fileName).fsPath;
        const dirPath = path.dirname(filePath);
        // 确保包含文件的目录存在
        await ensureDirectoryExists(dirPath);
        return filePath;
    }
    
    /**
     * 获取所有可用的MCP服务器
     */
    getServers() {
        if (!this.mcpHub) {
            throw new Error('MCP服务未初始化');
        }
        return this.mcpHub.getServers();
    }
    
    /**
     * 获取所有可用的MCP工具列表
     */
    getAvailableTools() {
        if (!this.mcpHub) {
            throw new Error('MCP服务未初始化');
        }
        
        const servers = this.mcpHub.getServers();
        const tools = [];
        
        for (const server of servers) {
            if (server.tools && !server.disabled) {
                for (const tool of server.tools) {
                    tools.push({
                        serverName: server.name,
                        toolName: tool.name,
                        description: tool.description,
                        autoApprove: !!tool.autoApprove,
                        properties: tool.inputSchema?.properties || {},
                        required: tool.inputSchema?.required || []
                    });
                }
            }
        }
        
        return tools;
    }
    
    /**
     * 获取单个服务器的工具列表
     */
    getServerTools(serverName) {
        if (!this.mcpHub) {
            throw new Error('MCP服务未初始化');
        }
        
        const server = this.mcpHub.getServers().find(s => s.name === serverName);
        if (!server) {
            throw new Error(`未找到服务器: ${serverName}`);
        }
        
        return server.tools || [];
    }
    
    /**
     * 调用MCP工具
     */
    async callTool(params) {
        if (!this.mcpHub) {
            throw new Error('MCP服务未初始化');
        }
        
        try {
            console.log(`调用MCP工具: ${params.serverName}.${params.toolName}`, params.params);
            
            // 确保params是合法的对象
            let toolParams = params.params;
            if (typeof toolParams === 'string') {
                try {
                    // 尝试将字符串参数解析为JSON对象
                    toolParams = JSON.parse(toolParams);
                } catch (e) {
                    console.warn('工具参数不是有效的JSON字符串:', e);
                    // 保持原字符串参数不变
                }
            }
            
            // 调用工具
            const result = await this.mcpHub.callTool(
                params.serverName,
                params.toolName,
                toolParams
            );
            
            return result;
        } catch (error) {
            console.error(`调用MCP工具失败: ${params.serverName}.${params.toolName}`, error);
            throw error;
        }
    }
    
    /**
     * 判断工具是否需要用户确认
     */
    isToolAutoApproved(serverName, toolName) {
        if (!this.mcpHub) {
            throw new Error('MCP服务未初始化');
        }
        
        const server = this.mcpHub.getServers().find(s => s.name === serverName);
        if (!server || !server.tools) {
            return false;
        }
        
        const tool = server.tools.find(t => t.name === toolName);
        return tool?.autoApprove || false;
    }
    
    /**
     * 启用/禁用服务器
     */
    async toggleServer(serverName, enabled) {
        if (!this.mcpHub) {
            throw new Error('MCP服务未初始化');
        }
        
        return await this.mcpHub.toggleServerDisabledRPC(serverName, !enabled);
    }
    
    /**
     * 添加新服务器
     */
    async addServer(serverName, serverUrl) {
        if (!this.mcpHub) {
            throw new Error('MCP服务未初始化');
        }
        
        return await this.mcpHub.addRemoteServer(serverName, serverUrl);
    }
    
    /**
     * 删除服务器
     */
    async deleteServer(serverName) {
        if (!this.mcpHub) {
            throw new Error('MCP服务未初始化');
        }
        
        await this.mcpHub.deleteServer(serverName);
    }
    
    /**
     * 更新服务器超时设置
     */
    async updateServerTimeout(serverName, timeout) {
        if (!this.mcpHub) {
            throw new Error('MCP服务未初始化');
        }
        
        return await this.mcpHub.updateServerTimeoutRPC(serverName, timeout);
    }
    
    /**
     * 更改工具的自动批准设置
     */
    async toggleToolAutoApprove(serverName, toolNames, autoApprove) {
        if (!this.mcpHub) {
            throw new Error('MCP服务未初始化');
        }
        
        await this.mcpHub.toggleToolAutoApprove(serverName, toolNames, autoApprove);
    }

    async getMcpSettingsFilePath() {
        if (!this.mcpHub) {
            throw new Error('MCP服务未初始化');
        }
        return this.mcpHub.getMcpSettingsFilePath();
    }
}

module.exports = { McpService }; 